#ifndef SM4_CRYPTO_H
#define SM4_CRYPTO_H

#include <stddef.h>
#include <gmssl/sm4.h>

// 使用GmSSL中的宏定义，避免重复定义
// SM4_KEY_SIZE 和 SM4_BLOCK_SIZE 已在 gmssl/sm4.h 中定义
#define SM4_IV_SIZE SM4_BLOCK_SIZE

/**
 * 生成随机SM4密钥
 * @param key 输出参数，用于存储生成的密钥，长度必须至少为SM4_KEY_SIZE(16字节)
 * @return 成功返回0，失败返回-1
 */
int generate_sm4_key(unsigned char *key);

/**
 * 生成随机初始化向量
 * @param iv 输出参数，用于存储生成的IV，长度必须至少为SM4_IV_SIZE(16字节)
 * @return 成功返回0，失败返回-1
 */
int generate_sm4_iv(unsigned char *iv);

/**
 * SM4-CBC模式加密数据
 * @param plaintext 明文数据
 * @param plaintext_len 明文长度
 * @param key 密钥，长度必须为SM4_KEY_SIZE(16字节)
 * @param iv 初始化向量，长度必须为SM4_IV_SIZE(16字节)
 * @param ciphertext 输出参数，用于存储加密后的密文
 * @param ciphertext_len 输入/输出参数，输入时表示ciphertext缓冲区大小，输出时表示实际密文长度
 * @return 成功返回0，缓冲区太小返回-2，其他错误返回-1
 */
int sm4_cbc_encrypt_data(const unsigned char *plaintext, size_t plaintext_len,
                         const unsigned char *key, const unsigned char *iv,
                         unsigned char *ciphertext, size_t *ciphertext_len);

/**
 * SM4-CBC模式解密数据
 * @param ciphertext 密文数据
 * @param ciphertext_len 密文长度，必须是SM4_BLOCK_SIZE(16字节)的整数倍
 * @param key 密钥，长度必须为SM4_KEY_SIZE(16字节)
 * @param iv 初始化向量，长度必须为SM4_IV_SIZE(16字节)
 * @param plaintext 输出参数，用于存储解密后的明文
 * @param plaintext_len 输入/输出参数，输入时表示plaintext缓冲区大小，输出时表示实际明文长度
 * @return 成功返回0，缓冲区太小返回-2，其他错误返回-1
 */
int sm4_cbc_decrypt_data(const unsigned char *ciphertext, size_t ciphertext_len,
                         const unsigned char *key, const unsigned char *iv,
                         unsigned char *plaintext, size_t *plaintext_len);

/**
 * SM4-CBC模式加密文件
 * @param input_file 输入文件路径
 * @param output_file 输出文件路径
 * @param key 密钥，长度必须为SM4_KEY_SIZE(16字节)
 * @param iv 初始化向量，长度必须为SM4_IV_SIZE(16字节)
 * @return 成功返回0，失败返回-1
 */
int sm4_encrypt_file(const char *input_file, const char *output_file,
                     const unsigned char *key, const unsigned char *iv);

/**
 * SM4-CBC模式解密文件
 * @param input_file 输入文件路径
 * @param output_file 输出文件路径
 * @param key 密钥，长度必须为SM4_KEY_SIZE(16字节)
 * @param iv 初始化向量，长度必须为SM4_IV_SIZE(16字节)，如果为NULL则从文件中读取
 * @return 成功返回0，失败返回-1
 */
int sm4_decrypt_file(const char *input_file, const char *output_file,
                     const unsigned char *key, const unsigned char *iv);

/**
 * 安全清除密钥数据
 * @param key 要清除的密钥数据
 * @param key_len 密钥长度
 */
void secure_clear_key(unsigned char *key, size_t key_len);

#endif /* SM4_CRYPTO_H */